/**
 * Created by wukong on 2018/5/28.
 */

import axios from 'axios';

function apiAxios (method, url, params = {}, resolve, reject) {
  utils.loadingStart();
  const token = '1'; // window.sessionStorage.getItem('rs_auth_token');
  let headers = {};
  if (token !== null && token !== '') {
    headers = { 'Vary': 'Accept-Encoding', 'Content-Type': 'application/json;charset=UTF-8', 'Authorization': token };
    axios({
      method: method,
      url: url,
      data: method === 'POST' || method === 'PUT' || method === 'PATCH' ? JSON.stringify(params) : null,
      params: method === 'GET' || method === 'DELETE' ? params : null,
      baseURL: process.env.API_ROOT,
      withCredentials: false,
      headers: headers
    }).then(function (res) {
      utils.loadingEnd();
      if (res.data.state === 'approved') {
        resolve(res.data);
      } else {
        reject(res.data);
      }
    }).catch(function (err) {
      utils.loadingEnd();
      let res = err.response;
      if (err) {
        console.warn('api error, HTTP CODE: ' + res.status);
      }
    });
  } else {
    // todo: 跳转登录
  }
}

const utils = {
  post (url, data = {}) {
    return new Promise((resolve, reject) => {
      apiAxios('POST', url, data, resolve, reject);
    });
  },
  get (url, data = {}) {
    return new Promise((resolve, reject) => {
      apiAxios('GET', url, data, resolve, reject);
    });
  },
  put (url, data = {}) {
    return new Promise((resolve, reject) => {
      apiAxios('PUT', url, data, resolve, reject);
    });
  },
  delete (url, data = {}) {
    return new Promise((resolve, reject) => {
      apiAxios('DELETE', url, data, resolve, reject);
    });
  },
  patch (url, data = {}) {
    return new Promise((resolve, reject) => {
      apiAxios('PATCH', url, data, resolve, reject);
    });
  },
  loadingStart () {
    const mask = document.createElement('div');
    const a = document.createElement('div');
    const b = document.createElement('div');
    const c = document.createElement('div');
    const d = document.createElement('div');
    const e = document.createElement('div');
    mask.className = 'mk-mask_transparent';
    mask.setAttribute('id', 'util-mask');
    a.className = 'loading-box b-center';
    a.setAttribute('id', 'util-loadBox');
    b.className = 'ball-beat';
    b.appendChild(c);
    b.appendChild(d);
    b.appendChild(e);
    a.appendChild(b);
    document.body.appendChild(mask);
    document.body.appendChild(a);
  },
  loadingEnd () {
    const mask = document.getElementById('util-mask');
    const a = document.getElementById('util-loadBox');
    document.body.removeChild(a);
    document.body.removeChild(mask);
  },
  /**
   * Deep copy the given object considering circular structure.
   * This function caches all nested objects and its copies.
   * If it detects circular structure, use cached copy to avoid infinite loop.
   *
   * @param {*} obj
   * @param {Array<Object>} cache
   * @return {*}
   */
  deepCopy (obj, cache = []) {
    // just return if obj is immutable value
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }

    // if obj is hit, it is in circular structure
    const hit = find(cache, c => c.original === obj);
    if (hit) {
      return hit.copy;
    }

    const copy = Array.isArray(obj) ? [] : {};
    // put the copy into cache at first
    // because we want to refer it in recursive deepCopy
    cache.push({
      original: obj,
      copy
    });

    Object.keys(obj).forEach((key) => {
      copy[key] = this.deepCopy(obj[key], cache);
    });

    return copy;
  }
};

export default {
  ...utils
};
